﻿using System;
using System.IO;
using System.Xml.Serialization;
using MECopter.Logging;
namespace MECopter.Configuration.GroundControl
{
    /// <summary>
    /// Reads and writes configuration fieles and holds current loaded configs
    /// </summary>
    static class ConfigurationManager
    {
        /// <summary>
        /// Current loaded general config
        /// </summary>
        public static GeneralConfig CurrentGeneralConfig;

        /// <summary>
        /// Current loaded serial config
        /// </summary>
        public static SerialConfig CurrentSerialConfig;

        /// <summary>
        /// Current loaded controller config
        /// </summary>
        public static ControllerConfig CurrentControllerConfig;

       
        private static TextWriter writeStream;
        private static FileStream readStream;

        /// <summary>
        /// Serializes and saves a SerialConfig object
        /// </summary>
        /// <param name="config">Config to save</param>
        public static void Save(GeneralConfig config)
        {
            try
            {
                Log.Info("Saving general config");
                CurrentGeneralConfig = config;

                XmlSerializer serializer = new XmlSerializer(typeof(GeneralConfig));
                writeStream = new StreamWriter("general.xml");
                serializer.Serialize(writeStream, config);

                writeStream.Close();
            }
            catch (Exception ex)
            {
                Log.Error(ex.ToString());
            }
        }

        /// <summary>
        /// Serializes and saves a SerialConfig object
        /// </summary>
        /// <param name="config">Config to save</param>
        public static void Save(SerialConfig config)
        {
            try
            {
                Log.Info("Saving serial config");
                CurrentSerialConfig = config;

                XmlSerializer serializer = new XmlSerializer(typeof(SerialConfig));
                writeStream = new StreamWriter("serial.xml");
                serializer.Serialize(writeStream, config);

                writeStream.Close();
            }
            catch (Exception ex)
            {
                Log.Error(ex.ToString());
            }
        }

        /// <summary>
        /// Serializes and saves a ControllerConfig object
        /// </summary>
        /// <param name="config">Config to save</param>
        public static void Save(ControllerConfig config)
        {
            try
            {
                Log.Info("Saving controller config");
                CurrentControllerConfig = config;

                XmlSerializer serializer = new XmlSerializer(typeof(ControllerConfig));
                writeStream = new StreamWriter("controller.xml");
                serializer.Serialize(writeStream, config);

                writeStream.Close();
            }
            catch (Exception ex)
            {
                Log.Error(ex.ToString());
            }
                   
        }

        /// <summary>
        /// Loads a config file of the given type an stores it in this class
        /// </summary>
        /// <param name="type">ConfigType to load</param>
        public static void Load(ConfigType type)
        {
            Config config;
            switch (type)
            {
                case ConfigType.General:
                    try
                    {
                        Log.Info("Loading general config");
                        XmlSerializer serializer = new XmlSerializer(typeof(GeneralConfig));
                        readStream = new FileStream("general.xml", FileMode.Open, FileAccess.Read, FileShare.Read);
                        config = (GeneralConfig)serializer.Deserialize(readStream);
                        CurrentGeneralConfig = (GeneralConfig)config;
                        readStream.Close();
                    }
                    catch (Exception ex)
                    {
                        Log.Error(ex.ToString());
                        GeneralConfig newConfig = new GeneralConfig();
                        newConfig.ShowConsole = GeneralConfig.DefaultShowConsole;
                        newConfig.UIRefreshRate = GeneralConfig.DefaultUIRefreshRate;
                        Save(newConfig);

                    }
                    break;

                case ConfigType.Serial:
                    try
                    {
                        Log.Info("Loading serial config");
                        XmlSerializer serializer = new XmlSerializer(typeof(SerialConfig));
                        readStream = new FileStream("serial.xml", FileMode.Open, FileAccess.Read, FileShare.Read);
                        config = (SerialConfig)serializer.Deserialize(readStream);
                        CurrentSerialConfig = (SerialConfig)config;
                        readStream.Close();
                    }
                    catch (Exception ex)
                    {
                        Log.Error(ex.ToString());
                        SerialConfig newConfig = new SerialConfig();
                        newConfig.Baudrate = SerialConfig.DefaultBaudrate;
                        newConfig.Port = SerialConfig.DefaultPort;
                        newConfig.SendInterval = SerialConfig.DefaultSendInterval;
                        Save(newConfig);
                       
                    }
                    break;

                case ConfigType.Controller:
                    try
                    {
                        Log.Info("Loading controller config");
                        XmlSerializer serializer = new XmlSerializer(typeof(ControllerConfig));
                        readStream = new FileStream("controller.xml", FileMode.Open, FileAccess.Read, FileShare.Read);
                        config = (ControllerConfig)serializer.Deserialize(readStream);
                        CurrentControllerConfig = (ControllerConfig)config;
                        readStream.Close();
                    }
                    catch (Exception ex)
                    {
                        Log.Error(ex.ToString());
                        ControllerConfig newConfig = new ControllerConfig();
                        newConfig.intervalTime = ControllerConfig.DefaultIntervalTime;                        
                        Save(newConfig);

                    }
                    break;
            }           
        }
    }
}
